package game;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: dima
 * Date: 2/8/13
 * Time: 3:46 AM
 */
public class Strategy implements StrategyIfc{

    private StrategyTable strategyTable = new StrategyTable();

    //THE MAIN METHOD
    @Override
    public char getNextMove(List<Card> playersCards, Card dealersCard, boolean playerHasOnlyTwoCards) {
        if(isFirstPair(playersCards)){
            return getNextMoveFromFirstPair(playersCards.get(0).getNumber(), dealersCard.getNumber(), playerHasOnlyTwoCards);
        } else if(isAceInCardsSet(playersCards)){
            return getNextMoveFromSetWithAce(playersCards, dealersCard, playerHasOnlyTwoCards);
        } else {
            return getNextMoveFromTotalNumber(playersCards, dealersCard, playerHasOnlyTwoCards);
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////////




    private boolean isAceInCardsSet(List<Card> playersCards) {
        for (Card playersCard : playersCards) {
            if(playersCard.getNumber().equals(Card.cardNumber.ACE)){
                return true;
            }
        }
        return false;
    }

    private boolean isFirstPair(List<Card> playersCards) {
        return (playersCards.size() == 2) && (playersCards.get(0).getNumber().equals(playersCards.get(1).getNumber()));
    }

    private char getNextMoveFromTotalNumber(List<Card> playersCards, Card dealersCard, boolean playerHasOnlyTwoCards) {
        String moveByStrategy = strategyTable.getNextMoveFromTotalNumber(Card.calculateSumFromCards(playersCards), dealersCard.getNumber());
        return getMoveBasedOnStrategy(moveByStrategy, playerHasOnlyTwoCards);
    }
    
    //precondition: no pair was at first place, still can be two aces inside, but not only two Aces
    private char getNextMoveFromSetWithAce(List<Card> playersCards, Card dealersCard, boolean playerHasOnlyTwoCards) {
        int sumWithoutAce = getCardsSumWithoutAce(playersCards);
        if(sumWithoutAce > 9){
            //treats Ace as 1
            return getNextMoveFromTotalNumber(playersCards, dealersCard, playerHasOnlyTwoCards);
        } else {
            String moveByStrategy = strategyTable.getNextMoveFromSetWithAce(sumWithoutAce, dealersCard.getNumber());
            return getMoveBasedOnStrategy(moveByStrategy, playerHasOnlyTwoCards);
        }
    }

    //any additional Ace is treated as 1
    private int getCardsSumWithoutAce(List<Card> playersCards) {
        int sum = 0;
        boolean aceWasAlready = false;
        for (Card playersCard : playersCards) {
            Card.cardNumber cardNumber = playersCard.getNumber();
            if(aceWasAlready){
                sum += Card.getIntValueFromCardNumber(cardNumber);
            } else {
                if (cardNumber.equals(Card.cardNumber.ACE)){
                    aceWasAlready = true;
                } else {
                    sum += Card.getIntValueFromCardNumber(cardNumber);
                }
            }
        }
        return sum;
    }

    private char getNextMoveFromFirstPair(Card.cardNumber playersCard, Card.cardNumber dealersCard, boolean playerHasOnlyTwoCards) {
        String moveByStrategy = strategyTable.getNextMoveFromPair(playersCard, dealersCard);
        return getMoveBasedOnStrategy(moveByStrategy, playerHasOnlyTwoCards);
    }

    private char getMoveBasedOnStrategy(String moveByStrategy, boolean playerHasOnlyTwoCards) {
        if(moveByStrategy.equals(StrategyTable.HIT)){
            return 'H';
        } else if(moveByStrategy.equals(StrategyTable.STAND)){
            return 'S';
        } else if(playerHasOnlyTwoCards){
            if(moveByStrategy.equals(StrategyTable.SPLIT)){
                return 'P';
            } else if(moveByStrategy.equals(StrategyTable.SPLIT_STAND)){
                return 'N';
            } else if(moveByStrategy.equals(StrategyTable.DOUBLE)){
                return 'D';
            } else if(moveByStrategy.equals(StrategyTable.DOUBLE_STAND)){
                return 'D';
            }
        } else {
            if(moveByStrategy.equals(StrategyTable.SPLIT)){
                //error: according to the table and the rules, can split only if has a pair
                throw new RuntimeException("Strategy got is SPLIT");
            } else if(moveByStrategy.equals(StrategyTable.SPLIT_STAND)){
                //error: according to the table and the rules, can split only if has a pair
                throw new RuntimeException("Strategy got is SPLIT_STAND");
            } else if(moveByStrategy.equals(StrategyTable.DOUBLE)){
                return 'H';
            } if(moveByStrategy.equals(StrategyTable.DOUBLE_STAND)){
                return 'S';
            }
        }
        //error
        return '?';
    }

}
